﻿using VSSLib;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.IO;
using System.Configuration;
using System.Threading;
namespace VSS.Testing
{


    /// <summary>
    ///This is a test class for SourceSafeTest and is intended
    ///to contain all SourceSafeTest Unit Tests
    ///</summary>
    [TestClass]
    public class SourceSafeTest
    {
        private static String _OriginalWorkingFolder;
        private static String _WorkingFolder;
        private static String _SrcIniFile;
        private static String _UserName;
        private static String _Password;
        private static String _TestUser;
        private static String _TestUserPassword;


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        [TestMethod]
        public void AddFileTest()
        {
            using (SourceSafe target = new SourceSafe())
            {
                target.OpenDatabase(_SrcIniFile, _UserName, _Password);

                try
                {
                    target.AddFile(null, null);
                    Assert.Fail("ArgumentNullException should be thrown.");
                }
                catch (ArgumentNullException) { }

                try
                {
                    target.AddFile(String.Empty, null);
                    Assert.Fail("ArgumentNullException should be thrown.");
                }
                catch (ArgumentNullException) { }

                try
                {
                    target.AddFile(@"$/", null);
                    Assert.Fail("ArgumentNullException should be thrown.");
                }
                catch (ArgumentNullException) { }

                try
                {
                    target.AddFile(@"$/", String.Empty);
                    Assert.Fail("ArgumentNullException should be thrown.");
                }
                catch (ArgumentNullException) { }


                String tempFile = _WorkingFolder + Path.DirectorySeparatorChar + System.IO.Path.GetRandomFileName();
                using (System.IO.StreamWriter w = new StreamWriter(tempFile))
                {
                    w.Write("test");
                    w.Flush();
                    w.Close();
                }

                byte[] originalBytes = File.ReadAllBytes(tempFile);
                try
                {
                    target.AddFile(@"$/", tempFile);
                    target.GetLatestVersion(@"$/" + Path.GetFileName(tempFile), true);

                    byte[] repBytes = File.ReadAllBytes(tempFile);

                    if (repBytes.Length != originalBytes.Length)
                        Assert.Fail("Add file failed, files are different.");


                    for (int i = 0; i < originalBytes.Length; i++)
                    {
                        if (repBytes[i] != originalBytes[i])
                            Assert.Fail("Add file failed, files are different.");
                    }

                }
                catch (SourceSafeException)
                {
                }
                finally
                {
                    try
                    {
                        target.Delete(@"$/" + Path.GetFileName(tempFile));
                    }
                    catch (SourceSafeException) { }
                }
            }

        }

        [TestMethod]
        public void CreateProjectTest()
        {
            String newSubProject = "newProject_" + Guid.NewGuid().ToString();

            using (SourceSafe target = new SourceSafe())
            {
                target.OpenDatabase(_SrcIniFile, _UserName, _Password);

                try
                {
                    target.CreateProject(null, null);
                    Assert.Fail("ArgumentNullException should be thrown.");
                }
                catch (ArgumentNullException) { }

                try
                {
                    target.CreateProject(String.Empty, null);
                    Assert.Fail("ArgumentNullException should be thrown.");
                }
                catch (ArgumentNullException) { }

                try
                {
                    target.CreateProject("$/", null);
                    Assert.Fail("ArgumentNullException should be thrown.");
                }
                catch (ArgumentNullException) { }

                try
                {
                    target.CreateProject("$/", String.Empty);
                    Assert.Fail("ArgumentNullException should be thrown.");
                }
                catch (ArgumentNullException) { }

                target.CreateProject("$/", newSubProject);

                List<String> items = target.GetSubProjects("$/");
                if (!items.Contains(newSubProject))
                    Assert.Fail(newSubProject);


                target.Delete("$/" + newSubProject);
            }
        }

        /// <summary>
        ///A test for OpenDatabase
        ///</summary>
        [TestMethod]
        public void OpenDatabaseTest()
        {


            using (SourceSafe target = new SourceSafe())
            {

                #region validation test
                try
                {
                    target.OpenDatabase(null,
                        _UserName,
                        _Password);
                    Assert.Fail("ArgumentNullException should be thrown");
                }
                catch (ArgumentNullException)
                {
                }

                try
                {
                    target.OpenDatabase(String.Empty,
                        _UserName,
                        _Password);
                    Assert.Fail("ArgumentNullException should be thrown");
                }
                catch (ArgumentNullException) { }

                try
                {
                    target.OpenDatabase(_SrcIniFile,
                        null,
                        _Password);
                    Assert.Fail("ArgumentNullException should be thrown");
                }
                catch (ArgumentNullException) { }

                try
                {
                    target.OpenDatabase(_SrcIniFile,
                       String.Empty,
                       _Password);
                    Assert.Fail("ArgumentNullException should be thrown");
                }
                catch (ArgumentNullException) { }
                #endregion

                target.OpenDatabase(_SrcIniFile,
                    _UserName,
                    _Password);
            }

        }

        [TestMethod]
        public void IsCheckedOutTest()
        {
            using (SourceSafe target = new SourceSafe())
            {
                target.OpenDatabase(_SrcIniFile, _UserName, _Password);

                String user = null;

                #region validation test

                try
                {
                    target.IsCheckedOut(null, out user);
                    Assert.Fail("ArgumentNullException expected.");
                }
                catch (ArgumentNullException)
                {
                }

                try
                {
                    target.IsCheckedOut(String.Empty, out user);
                    Assert.Fail("ArgumentNullException expected.");
                }
                catch (ArgumentNullException)
                {
                }

                #endregion

                #region plik nie istnieje w repozytorium
                try
                {
                    var isCheckedOut = target.IsCheckedOut(@"/notexistingfile", out user);
                    Assert.Fail("SourceSafeException expected");
                }
                catch (SourceSafeException) { }
                #endregion

                #region podana sciezka jest projektem
                try
                {
                    var isCheckedOut = target.IsCheckedOut(@"/project3", out user);
                    Assert.Fail("SourceSafeException expected");
                }
                catch (SourceSafeException) { }
                #endregion

                bool actual = target.IsCheckedOut(@"/project3/file3.txt", out user);
                bool expected = false;
                Assert.AreEqual(actual, expected);

                try
                {
                    target.CheckOutFile(@"/project3/file3.txt");
                    actual = target.IsCheckedOut(@"/project3/file3.txt", out user);

                    expected = true;
                    Assert.AreEqual(actual, expected);

                    String expectedUser = _UserName;
                    String actualUser = user;
                    Assert.AreEqual(expectedUser, actualUser);
                }
                finally
                {
                    try
                    {
                        target.UndoCheckOut(@"/project3/file3.txt");
                    }
                    catch (SourceSafeException)
                    {
                    }
                }
            }
        }

        #region GetLatestVersionTest
        [TestMethod]
        public void GetLatestVersionTest()
        {
            using (SourceSafe target = new SourceSafe())
            {
                target.OpenDatabase(_SrcIniFile, _UserName, _Password);

                #region validation test
                try
                {
                    target.GetLatestVersion(null, false);
                    Assert.Fail("Method should throw ArgumentNulLException.");
                }
                catch (ArgumentNullException) { }

                try
                {
                    target.GetLatestVersion(String.Empty, false);
                    Assert.Fail("Method should throw ArgumentNulLException.");

                }
                catch (ArgumentNullException) { }
                #endregion

                ClearLocalCopyFolder();

                #region non recursive test
                target.GetLatestVersion("$/", false);

                string[] testFiles = Directory.GetFiles(testContextInstance.TestDeploymentDir + Path.DirectorySeparatorChar + "VSSLocalCopy", "*.*", SearchOption.TopDirectoryOnly);

                foreach (String testFile in testFiles)
                {
                    String localCopyFile = testFile.Replace((testContextInstance.TestDeploymentDir + Path.DirectorySeparatorChar + "VSSLocalCopy"), _WorkingFolder);
                    if (!File.Exists(localCopyFile))
                        Assert.Fail("Plik nie istnieje " + localCopyFile);

                    byte[] testFileBytes = File.ReadAllBytes(testFile);
                    byte[] localCopyFileBytes = File.ReadAllBytes(localCopyFile);

                    if (testFileBytes.Length != localCopyFileBytes.Length)
                        Assert.Fail("Pliki nie są identyczne: " + testFile + ", " + localCopyFile);

                    for (int i = 0; i < testFileBytes.Length; i++)
                    {
                        if (testFileBytes[i] != localCopyFileBytes[i])
                            Assert.Fail("Pliki nie są identyczne: " + testFile + ", " + localCopyFile);

                    }

                }
                #endregion

                ClearLocalCopyFolder();

                #region getting empty project test
                target.GetLatestVersion(@"$/emptyproject", false);
                CompareFolder(testContextInstance.TestDeploymentDir + Path.DirectorySeparatorChar + "VSSLocalCopy" + Path.DirectorySeparatorChar + "emptyproject", _WorkingFolder + Path.DirectorySeparatorChar + @"emptyproject");
                #endregion

                ClearLocalCopyFolder();

                #region recursive test
                target.GetLatestVersion("$/", true);

                CompareFolder(testContextInstance.TestDeploymentDir + Path.DirectorySeparatorChar + "VSSLocalCopy", _WorkingFolder);
                #endregion

                ClearLocalCopyFolder();
                #region getting file with no readonly attribute test

                target.GetLatestVersion(@"$/project2/file1.ini", false);
                String bootIniFileOriginal = testContextInstance.TestDeploymentDir + Path.DirectorySeparatorChar + "VSSLocalCopy" + Path.DirectorySeparatorChar + "project2" + Path.DirectorySeparatorChar + "file1.ini";
                String bootIniFileWorkingCopy = _WorkingFolder + Path.DirectorySeparatorChar + "project2" + Path.DirectorySeparatorChar + "file1.ini";

                FileInfo fileInfo = new FileInfo(bootIniFileWorkingCopy);
                if ((fileInfo.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                {
                    fileInfo.Attributes = fileInfo.Attributes & ~FileAttributes.ReadOnly;
                }

                File.WriteAllText(bootIniFileWorkingCopy, "test1234");

                target.GetLatestVersion(@"$/project2/file1.ini", false);
                if (!CompareFiles(bootIniFileOriginal, bootIniFileWorkingCopy))
                    Assert.Fail(string.Format("Files {0} and {1} are different.", bootIniFileOriginal, bootIniFileWorkingCopy));
                #endregion

                ClearLocalCopyFolder();
                #region getting only different file
                String msdossysFileOriginal = testContextInstance.TestDeploymentDir + Path.DirectorySeparatorChar + "VSSLocalCopy" + Path.DirectorySeparatorChar + "project3" + Path.DirectorySeparatorChar + "file1.txt";
                String msdosysFileWorkingCopy = _WorkingFolder + Path.DirectorySeparatorChar + "project3" + Path.DirectorySeparatorChar + "file1.txt";

                target.GetLatestVersion(@"/project3/file1.txt",false);

                fileInfo = new FileInfo(msdosysFileWorkingCopy);
                if ((fileInfo.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                {
                    fileInfo.Attributes = fileInfo.Attributes & ~FileAttributes.ReadOnly;
                }

                target.GetLatestVersion(@"/project3/file1.txt", false,true);
                fileInfo = new FileInfo(msdosysFileWorkingCopy);
                if ((fileInfo.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                    Assert.Fail("Getting only different file failed.");

                File.WriteAllText(msdosysFileWorkingCopy, "test1234");

                target.GetLatestVersion(@"/project3/file1.txt", false, true);
                fileInfo = new FileInfo(msdosysFileWorkingCopy);
                if ((fileInfo.Attributes & FileAttributes.ReadOnly) != FileAttributes.ReadOnly)
                    Assert.Fail("Getting only different file failed.");


                if (!CompareFiles(msdossysFileOriginal, msdosysFileWorkingCopy))
                    Assert.Fail(string.Format("Files {0} and {1} are different.", msdossysFileOriginal, msdosysFileWorkingCopy));
                #endregion

                ClearLocalCopyFolder();

                #region getting only different file, but file doesnt exists in working localcopy
                target.GetLatestVersion(@"/project3/file1.txt", false, true);
                if (!File.Exists(msdosysFileWorkingCopy))
                    Assert.Fail(string.Format("File {0} doesnt exists.", msdosysFileWorkingCopy));

                if (!CompareFiles(msdossysFileOriginal, msdosysFileWorkingCopy))
                    Assert.Fail(string.Format("Files {0} and {1} are different.", msdossysFileOriginal, msdosysFileWorkingCopy));
                #endregion
            }
        }

        private void CompareFolder(String deploymentLocalCopyFolder, String localCopyFolder)
        {
            if (!Directory.Exists(deploymentLocalCopyFolder))
                Assert.Fail(string.Format("Directory {0} doesnt exists.", deploymentLocalCopyFolder));
            if(!Directory.Exists(localCopyFolder))
                Assert.Fail(string.Format("Directory {0} doesnt exists.", localCopyFolder));

            String[] testFiles = Directory.GetFiles(deploymentLocalCopyFolder, "*.*", SearchOption.TopDirectoryOnly);

            foreach (String testFile in testFiles)
            {
                //String localCopyFile = testFile.Replace((testContextInstance.TestDeploymentDir + Path.DirectorySeparatorChar + "VSSLocalCopy"), _WorkingFolder);
                String localCopyFile = localCopyFolder + Path.DirectorySeparatorChar + Path.GetFileName(testFile);

                if (localCopyFile.Contains(".svn"))
                    continue;

                if (!File.Exists(localCopyFile))
                    Assert.Fail("Plik nie istnieje " + localCopyFile);

                byte[] testFileBytes = File.ReadAllBytes(testFile);
                byte[] localCopyFileBytes = File.ReadAllBytes(localCopyFile);

                if (testFileBytes.Length != localCopyFileBytes.Length)
                    Assert.Fail("Pliki nie są identyczne: " + testFile + ", " + localCopyFile);

                for (int i = 0; i < testFileBytes.Length; i++)
                {
                    if (testFileBytes[i] != localCopyFileBytes[i])
                        Assert.Fail("Pliki nie są identyczne: " + testFile + ", " + localCopyFile);

                }

            }

            String[] testFolders = Directory.GetDirectories(deploymentLocalCopyFolder, "*.*", SearchOption.TopDirectoryOnly);
            foreach (String testFolder in testFolders)
            {
                if (testFolder.Contains(".svn"))
                    continue;
                String newlocalCopyFolder = localCopyFolder + Path.DirectorySeparatorChar + testFolder.Substring(testFolder.LastIndexOf(@"\") + 1);
                if (!Directory.Exists(newlocalCopyFolder))
                    Assert.Fail("Directory doesnt exists " + newlocalCopyFolder);

                CompareFolder(testFolder, newlocalCopyFolder);
            }


        }

        #endregion

        [TestMethod]
        public void CheckOutFileTest()
        {
            using (SourceSafe target = new SourceSafe())
            {
                target.OpenDatabase(_SrcIniFile, _UserName, _Password);

                #region validation test
                try
                {
                    target.CheckOutFile(null);
                    Assert.Fail("Expected ArgumentNullException.");
                }
                catch (ArgumentNullException) { }

                try
                {
                    target.CheckOutFile(String.Empty);
                    Assert.Fail("Expected ArgumentNullException.");
                }
                catch (ArgumentNullException) { }
                #endregion

                #region proba wycheckoutowania niestniejacego pliku w rep
                try
                {
                    String fileName = Path.GetRandomFileName();
                    target.CheckOutFile(@"$/" + fileName);
                }
                catch (SourceSafeException) { }
                #endregion

                #region checkout powinien utworzyc plik na dysku jesli go nie ma




                string localcopyFile = _WorkingFolder + @"\project3\file3.txt";
                string testFile = testContextInstance.TestDeploymentDir + Path.DirectorySeparatorChar + "VSSLocalCopy" + Path.DirectorySeparatorChar + @"project3\file3.txt";

                if (File.Exists(localcopyFile))
                {
                    File.SetAttributes(localcopyFile, FileAttributes.Normal);
                    File.Delete(localcopyFile);
                }

                byte[] localCopyBytes;
                byte[] bytesTest;
                try
                {
                    target.CheckOutFile(@"$/project3/file3.txt");

                    if (!File.Exists(localcopyFile))
                        Assert.Fail("Checkout pliku nie powiodl sie. Brak pliku na dysku " + localcopyFile);

                    localCopyBytes = File.ReadAllBytes(_WorkingFolder + @"\project3\file3.txt");
                    bytesTest = File.ReadAllBytes(testFile);

                    if (localCopyBytes.Length != bytesTest.Length)
                        Assert.Fail("Pliki nie są identyczne: " + testFile + ", " + localcopyFile);

                    for (int i = 0; i < bytesTest.Length; i++)
                    {
                        if (bytesTest[i] != localCopyBytes[i])
                            Assert.Fail("Pliki nie są identyczne: " + testFile + ", " + localcopyFile);

                    }
                }
                finally
                {
                    target.UndoCheckOut(@"$/project3/file3.txt");
                }
                #endregion

                #region checkout powinien nadpisac plik ktory nie ma atrybutu read-only

                string otherFile = _WorkingFolder + @"\project3\file2.txt";
                target.GetLatestVersion(@"$/project3/file2.txt", false);
                byte[] otherFileBytes = File.ReadAllBytes(otherFile);


                File.SetAttributes(localcopyFile, FileAttributes.Normal);
                File.Delete(localcopyFile);
                using (FileStream stream = File.OpenWrite(localcopyFile))
                {
                    stream.Write(otherFileBytes, 0, otherFileBytes.Length);
                    stream.Flush();
                    stream.Close();
                }

                try
                {
                    target.CheckOutFile(@"$/project3/file3.txt");

                    if (!File.Exists(localcopyFile))
                        Assert.Fail("Checkout pliku nie powiodl sie. Brak pliku na dysku " + localcopyFile);

                    localCopyBytes = File.ReadAllBytes(_WorkingFolder + @"\project3\file3.txt");
                    bytesTest = File.ReadAllBytes(testFile);

                    if (localCopyBytes.Length != bytesTest.Length)
                        Assert.Fail("Pliki nie są identyczne: " + testFile + ", " + localcopyFile);

                    for (int i = 0; i < bytesTest.Length; i++)
                    {
                        if (bytesTest[i] != localCopyBytes[i])
                            Assert.Fail("Pliki nie są identyczne: " + testFile + ", " + localcopyFile);

                    }
                }
                finally
                {
                    target.UndoCheckOut(@"$/project3/file3.txt");
                }
                #endregion
            }
        }

        [TestMethod]
        public void UndoCheckOutTest()
        {
            using (SourceSafe vssTest = new SourceSafe())
            {
                vssTest.OpenDatabase(_SrcIniFile, _TestUser, _TestUserPassword);


                using (SourceSafe target = new SourceSafe())
                {
                    target.OpenDatabase(_SrcIniFile, _UserName, _Password);


                    #region validation test
                    try
                    {
                        target.UndoCheckOut(null);
                        Assert.Fail("Expected ArgumentNullException.");
                    }
                    catch (ArgumentNullException) { }

                    try
                    {
                        target.UndoCheckOut(String.Empty);
                        Assert.Fail("Expected ArgumentNullException.");
                    }
                    catch (ArgumentNullException) { }
                    #endregion

                    #region plik nie jest wycheckoutowany
                    try
                    {
                        target.UndoCheckOut(@"$/project3/file2.txt");
                        Assert.Fail("Expected SourceSafeException.");
                    }
                    catch (SourceSafeException) { }
                    #endregion


                    #region plik jest wycheckoutowany na innego usera


                    vssTest.CheckOutFile(@"$/project3/file3.txt");
                    try
                    {

                        target.UndoCheckOut(@"$/project3/file3.txt");
                        Assert.Fail("SourceSafeException expected.");
                    }
                    catch (SourceSafeException) { }
                    finally
                    {
                        vssTest.UndoCheckOut(@"$/project3/file3.txt");
                    }
                    #endregion


                    #region pliku nie ma na dysku

                    target.CheckOutFile(@"$/project3/file3.txt");

                    if (File.Exists(_WorkingFolder + @"\project3\file3.txt.TEST"))
                        File.Delete(_WorkingFolder + @"\project3\file3.txt.TEST");

                    if (File.Exists(_WorkingFolder + @"\project3\file3.txt"))
                        File.Move(_WorkingFolder + @"\project3\file3.txt", _WorkingFolder + @"\project3\file3.txt.TEST");
                    try
                    {
                        target.UndoCheckOut(@"$/project3/file3.txt");
                        Assert.Fail("SourceSafeException expected.");
                    }
                    catch (SourceSafeException) { }
                    finally
                    {
                        File.Move(_WorkingFolder + @"\project3\file3.txt.TEST", _WorkingFolder + @"\project3\file3.txt");
                        target.UndoCheckOut(@"$/project3/file3.txt");
                    }
                    #endregion

                    #region undocheckoutowanie pliku powinno nadpisac plik wersja z repozytorium
                    target.GetLatestVersion(@"$/project3/file2.txt", false);
                    String fakeFile = _WorkingFolder + @"\project3\file2.txt";
                    byte[] fakeBytes = File.ReadAllBytes(fakeFile);

                    target.CheckOutFile(@"$/project3/file3.txt");

                    File.SetAttributes(_WorkingFolder + @"\project3\file3.txt", FileAttributes.Normal);
                    File.Delete(_WorkingFolder + @"\project3\file3.txt");
                    using (FileStream stream = File.OpenWrite(_WorkingFolder + @"\project3\file3.txt"))
                    {
                        stream.Write(fakeBytes, 0, fakeBytes.Length);
                        stream.Flush();
                        stream.Close();
                    }

                    target.UndoCheckOut(@"$/project3/file3.txt");

                    String originalFile = testContextInstance.TestDeploymentDir + Path.DirectorySeparatorChar + "VSSLocalCopy" + Path.DirectorySeparatorChar + @"project3\file3.txt";
                    String testFile = _WorkingFolder + @"\project3\file3.txt";
                    byte[] originalBytes = File.ReadAllBytes(originalFile);
                    byte[] testBytes = File.ReadAllBytes(testFile);

                    if (originalBytes.Length != testBytes.Length)
                        Assert.Fail("Pliki nie są identyczne: " + testFile + ", " + originalFile);

                    for (int i = 0; i < originalBytes.Length; i++)
                    {
                        if (testBytes[i] != originalBytes[i])
                            Assert.Fail("Pliki nie są identyczne: " + testFile + ", " + originalFile);

                    }
                    #endregion

                    #region plik jest wycheckoutowany na mnie ale na innym komputerze
                    Assert.Inconclusive("Nie wiem jak to przetestowac.");
                    #endregion

                }
            }
        }

        [TestMethod]
        public void CheckInFileTest()
        {
            using (SourceSafe vssTest = new SourceSafe())
            {
                vssTest.OpenDatabase(_SrcIniFile, _TestUser, _TestUserPassword);
                using (SourceSafe target = new SourceSafe())
                {
                    target.OpenDatabase(_SrcIniFile, _UserName, _Password);

                    #region validation test
                    try
                    {
                        target.CheckIn(null);
                    }
                    catch (ArgumentNullException) { }

                    try
                    {
                        target.CheckIn(String.Empty);
                    }
                    catch (ArgumentNullException) { }
                    #endregion

                    #region plik nie jest wycheckotowany
                    try
                    {
                        target.CheckIn(@"$/project3/file2.txt");
                        Assert.Fail("Expected SourceSafeException.");
                    }
                    catch (SourceSafeException) { }
                    #endregion

                    #region plik jest wycheckotowany na innego usera
                    vssTest.CheckOutFile(@"$/project3/file3.txt");
                    try
                    {

                        target.CheckIn(@"$/project3/file3.txt");
                        Assert.Fail("SourceSafeException expected.");
                    }
                    catch (SourceSafeException) { }
                    finally
                    {
                        vssTest.UndoCheckOut(@"$/project3/file3.txt");
                    }
                    #endregion



                    #region pliku nie ma dysku
                    target.CheckOutFile(@"$/project3/file3.txt");

                    if (File.Exists(_WorkingFolder + @"\project3\file3.txt.TEST"))
                        File.Delete(_WorkingFolder + @"\project3\file3.txt.TEST");

                    if (File.Exists(_WorkingFolder + @"\project3\file3.txt"))
                        File.Move(_WorkingFolder + @"\project3\file3.txt", _WorkingFolder + @"\project3\file3.txt.TEST");
                    try
                    {
                        target.CheckIn(@"$/project3/file3.txt");
                        Assert.Fail("SourceSafeException expected.");
                    }
                    catch (SourceSafeException) { }
                    finally
                    {
                        File.Move(_WorkingFolder + @"\project3\file3.txt.TEST", _WorkingFolder + @"\project3\file3.txt");
                        target.UndoCheckOut(@"$/project3/file3.txt");
                    }
                    #endregion

                    #region porownanie pliku wcheckinowanego z kopia na dysku czy sa identyczne
                    target.GetLatestVersion(@"/project3/file2.txt", false);
                    target.CheckOutFile(@"$/project3/file3.txt");

                    byte[] oldBytes;
                    byte[] newBytes;
                    try
                    {
                        oldBytes = File.ReadAllBytes(_WorkingFolder + Path.DirectorySeparatorChar + "project3" + Path.DirectorySeparatorChar + "file3.txt");
                        newBytes = File.ReadAllBytes(_WorkingFolder + Path.DirectorySeparatorChar + "project3" + Path.DirectorySeparatorChar + "file2.txt");
                        File.Delete(_WorkingFolder + Path.DirectorySeparatorChar + "project3" + Path.DirectorySeparatorChar + "file3.txt");
                        using (FileStream stream = File.OpenWrite(_WorkingFolder + Path.DirectorySeparatorChar + "project3" + Path.DirectorySeparatorChar + "file3.txt"))
                        {
                            stream.Write(newBytes, 0, newBytes.Length);
                            stream.Flush();
                            stream.Close();
                        }

                        target.CheckIn(@"/project3/file3.txt");
                    }
                    catch (SourceSafeException)
                    {
                        try
                        {
                            target.UndoCheckOut(@"$/project3/file3.txt");
                        }
                        catch (SourceSafeException) { }
                        throw;
                    }
                    target.GetLatestVersion(@"/project3/file3.txt", false);
                    byte[] repBytes = File.ReadAllBytes(_WorkingFolder + Path.DirectorySeparatorChar + "project3" + Path.DirectorySeparatorChar + "file3.txt");


                    bool theSame = true;
                    if (repBytes.Length != newBytes.Length)
                        theSame = false;
                    for (int i = 0; i < newBytes.Length; i++)
                    {
                        if (repBytes[i] != newBytes[i])
                        {
                            theSame = false;
                            break;
                        }
                    }

                    #region przywracamy poprzednia wersje pliku
                    target.CheckOutFile(@"$/project3/file3.txt");
                    File.Delete(_WorkingFolder + Path.DirectorySeparatorChar + "project3" + Path.DirectorySeparatorChar + "file3.txt");
                    using (FileStream stream = File.OpenWrite(_WorkingFolder + Path.DirectorySeparatorChar + "project3" + Path.DirectorySeparatorChar + "file3.txt"))
                    {
                        stream.Write(oldBytes, 0, oldBytes.Length);
                        stream.Flush();
                        stream.Close();
                    }
                    target.CheckIn(@"$/project3/file3.txt");
                    #endregion

                    if (!theSame)
                        Assert.Fail("Checking failed, files are different.");

                    #endregion

                    #region plik jest wycheckoutowany na mnie ale na innym kompie
                    Assert.Inconclusive("Nie wiem jak to przetestowac.");
                    #endregion
                }
            }
        }

        [TestMethod]
        public void SetWorkingFolderTest()
        {
            GetWorkingFolderTest();
        }

        [TestMethod]
        public void GetWorkingFolderTest()
        {
            using (SourceSafe target = new SourceSafe())
            {
                target.OpenDatabase(_SrcIniFile, _UserName, _Password);

                #region validation test
                try
                {
                    target.GetWorkingFolder(null);
                    Assert.Fail("ArgumentNullExpected");
                }
                catch (ArgumentNullException) { }

                try
                {
                    target.GetWorkingFolder(String.Empty);
                    Assert.Fail("ArgumentNullExpected");
                }
                catch (ArgumentNullException) { }
                #endregion

                String originalWorkingFolder = null;
                try
                {
                    originalWorkingFolder = target.GetWorkingFolder(@"$/");

                    target.SetWorkingFolder(@"$/", _WorkingFolder);
                    String actual = target.GetWorkingFolder(@"$/");
                    String expected = _WorkingFolder;

                    Assert.AreEqual(expected, actual);
                }
                finally
                {
                    try
                    {
                        target.SetWorkingFolder("$/", originalWorkingFolder);
                    }
                    catch (SourceSafeException) { }
                }
            }
        }

        [TestMethod]
        public void GetParentTest()
        {
            Assert.Inconclusive("Niezaimplementowana metoda.");
        }

        [TestMethod]
        public void RenameTest()
        {
            using (SourceSafe target = new SourceSafe())
            {
                target.OpenDatabase(_SrcIniFile, _UserName, _Password);
                #region validation test
                try
                {
                    target.Rename(null, "newName");
                    Assert.Fail("ArgumentNullException expected.");
                }
                catch (ArgumentNullException) { }

                try
                {
                    target.Rename(String.Empty, "newName");
                    Assert.Fail("ArgumentNullException expected.");
                }
                catch (ArgumentNullException) { }

                try
                {
                    target.Rename(@"$/nonexistingproject", null);
                    Assert.Fail("ArgumentNullException expected.");
                }
                catch (ArgumentNullException) { }

                try
                {
                    target.Rename(@"$/nonexistingproject", String.Empty);
                    Assert.Fail("ArgumentNullException expected.");
                }
                catch (ArgumentNullException) { }
                #endregion

                String phisicalFilePath = _WorkingFolder + Path.DirectorySeparatorChar + "project3" + Path.DirectorySeparatorChar + "file1.txt";
                String filePath = @"$/project3/file1.txt";
                String fileName = "file1.txt";
                String newPhisicalFilePath = _WorkingFolder + Path.DirectorySeparatorChar + "project3" + Path.DirectorySeparatorChar + "zupa.123";
                String newFilePath = @"$/project3/zupa.123";
                String newName = "zupa.123";
                try
                {
                    target.GetLatestVersion(filePath, false);

                    target.Rename(filePath, newName);
                    target.GetLatestVersion(newFilePath, false);

                    if (!CompareFiles(phisicalFilePath, newPhisicalFilePath))
                    {
                        Assert.Fail(String.Format("Files {0} and {1} are not the same.", phisicalFilePath, newPhisicalFilePath));
                    }


                }
                finally
                {
                    #region undo
                    try
                    {
                        target.Rename(newFilePath, fileName);
                    }
                    catch (SourceSafeException) { }
                    #endregion
                }
            }
        }

        [TestMethod]
        public void ShareTest()
        {
            Assert.Inconclusive("Brak implementacji");
        }

        [TestMethod]
        public void DestroyTest()
        {
            Assert.Inconclusive("Brak implementacji");
        }

        [TestMethod]
        public void LabelTest()
        {
            Assert.Inconclusive("Niezaimplementowana metoda.");
        }

        [TestMethod]
        public void GetVersionsTest()
        {
            Assert.Inconclusive("Niezaimplementowana metoda.");
        }

        [TestMethod]
        public void GetChildsTest()
        {
            Assert.Inconclusive("Niezaimplementowana metoda.");
        }

        private bool CompareFiles(String file1, String file2)
        {
            byte[] bytes1 = File.ReadAllBytes(file1);
            byte[] bytes2 = File.ReadAllBytes(file2);

            if (bytes1.Length != bytes2.Length)
                return false;
            for (int i = 0; i < bytes1.Length; i++)
            {
                if (bytes1[i] != bytes2[i])
                {
                    return false;
                }
            }

            return true;
        }

        private void ClearLocalCopyFolder()
        {
            #region clear folder with localcopy

            string[] files = Directory.GetFiles(_WorkingFolder, "*.*", SearchOption.AllDirectories);
            foreach (string file in files)
            {
                FileInfo fileInfo = new FileInfo(file);
                if ((fileInfo.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                {
                    fileInfo.Attributes = fileInfo.Attributes & ~FileAttributes.ReadOnly;
                }
                File.Delete(file);

            }
            #endregion

            string[] directories = Directory.GetDirectories(_WorkingFolder, "*.*", SearchOption.TopDirectoryOnly);
            foreach (String dir in directories)
            {
                Directory.Delete(dir, true);
            }


        }

        [ClassInitialize]
        public static void Initialize(TestContext testContext)
        {
            _WorkingFolder = testContext.TestDeploymentDir + Path.DirectorySeparatorChar + "VSSWorkingFolder";
            _SrcIniFile = ConfigurationManager.AppSettings["SrcIniFile"];
            _UserName = ConfigurationManager.AppSettings["UserName"];
            _Password = ConfigurationManager.AppSettings["Password"];
            _TestUser = ConfigurationManager.AppSettings["TestUser"];
            _TestUserPassword = ConfigurationManager.AppSettings["TestUserPassword"];

            #region creating and setting working folder

            if (!Directory.Exists(_WorkingFolder))
                Directory.CreateDirectory(_WorkingFolder);

            using (SourceSafe target = new SourceSafe())
            {
                target.OpenDatabase(_SrcIniFile, _UserName, _Password);

                _OriginalWorkingFolder = target.GetWorkingFolder(@"$/");
                target.SetWorkingFolder(@"$/", _WorkingFolder);
            }
            #endregion
        }

        [ClassCleanup]
        public static void CleanUp()
        {
            using (SourceSafe target = new SourceSafe())
            {
                target.OpenDatabase(_SrcIniFile, _UserName, _Password);

                target.SetWorkingFolder(@"$/", _OriginalWorkingFolder);
            }
        }
    }
}
